package sg.edu.nus.iss.cerberus.wizard;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.StringTokenizer;

import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.ui.wizards.NewTypeWizardPage;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchPart;
import sg.edu.nus.iss.cerberus.engine.CClassBuilder;
import sg.edu.nus.iss.cerberus.engine.JUnitMethodCheck;
import sg.edu.nus.iss.cerberus.model.CClass;
import sg.edu.nus.iss.cerberus.model.CMemberMethod;
import sg.edu.nus.iss.cerberus.model.MethodTestData;
import sg.edu.nus.iss.cerberus.model.TestGenerationData;

import sg.edu.nus.iss.cerberus.util.CerberusConstants;
import sg.edu.nus.iss.cerberus.util.CerberusMethodsDelegate;
import sg.edu.nus.iss.cerberus.views.CerberusTestGen;

public class NewTestMethodWizardPage extends NewTypeWizardPage {
	private Text fileText;

	private ISelection selection;

	private ArrayList<CMemberMethod> cmmethods;
	private Combo methodNames;
	//private ParserDropDown pDropDown;
	private IWorkbenchPart part;
	private HashMap<String, ArrayList<String>> hashMethods;
	private Iterator<CMemberMethod> iter;
	public CerberusTestGen cerbTestGen;
	private HashMap<String, ArrayList<CMemberMethod>> methods;
	public ArrayList<ArrayList<CMemberMethod>> alist;
	public ArrayList<CMemberMethod> memberMethod;
	public ArrayList<String> methodsParameters;
	private TestGenerationData testGenData;
	int numberOfRows = 1;
	int numberOfCols = 7;
	Text[][] txtBox = new Text[numberOfRows][numberOfCols];
	Label[] lbl = new Label[numberOfRows];
	// final static String[] methods ={ "1", "2", "3", "4", "5", "6"};
	private String[] items = { CerberusConstants.ASSERTTRUE, CerberusConstants.ASSERTFALSE, CerberusConstants.ASSERTNOTNULL,CerberusConstants.ASSERTEQUALS};
	CCombo[] combo = new CCombo[numberOfRows];
	String[][] data = new String[numberOfRows][numberOfCols];
	private Label label1,label2,label3,label4;
	public NewTestMethodWizardPage(ISelection selection, IWorkbenchPart part) {
		super(true, "wizardPage");
		super.setTitle("Cerberus Test Case Generation");
		setDescription("This wizard creates a new Test Cases for *.Java extension files.");
		this.selection = selection;
		this.part = part;
		// pDropDown = new ParserDropDown(part);
		hashMethods = new HashMap<String, ArrayList<String>>();
		methodsParameters = new ArrayList<String>();
		testGenData = new TestGenerationData();
	}


	public void createControl(Composite parent) {
		Composite container = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		container.setLayout(layout);
		layout.numColumns = 7;
		layout.verticalSpacing = 20;
		Label label = new Label(container, SWT.NULL);
		label.setText("&Test Class:");

		// cmmethods = pDropDown.MethodsInCUT();
		cmmethods = MethodsInCUT();

		label = new Label(container, SWT.NULL);
		label.setText("" + part.getTitle());
		label3 = new Label(container, SWT.NULL);
		label3.setText("");
		label1 = new Label(container, SWT.NULL);
		label1.setText("Method Name: ");
		//		label1.setFont(new Font("Serif",java.awt.Font.BOLD, 48));
		ArrayList<String> methods = new ArrayList<String>();

		iter = cmmethods.iterator();
		while (iter.hasNext()) {
			CMemberMethod cmm = iter.next();
			//	methods.add(cmm.getMethodName());
			methods.add(cmm.getFullSignature());
		}


		label2 = new Label(container, SWT.NULL);
		label2.setText("");
		label4 = new Label(container, SWT.NULL);
		label4.setText("");

		// methodNames
		methodNames = new Combo(container, SWT.BORDER | SWT.READ_ONLY);
		GridData gd = new GridData();
		gd.horizontalAlignment = GridData.BEGINNING;
		methodNames.setLayoutData(gd);

		//adding the values in combo
		methodNames.setItems(methods.toArray(new String[methods.size()]));

		label4 = new Label(container, SWT.NULL);
		label4.setText("Select Asserts");
		label4 = new Label(container, SWT.NULL);
		label4.setText("Expected Value");
		label4 = new Label(container, SWT.NULL);
		label4.setText("Parameter1");
		label4 = new Label(container, SWT.NULL);
		label4.setText("Parameter2");
		label4 = new Label(container, SWT.NULL);
		label4.setText("Parameter3");
		label4 = new Label(container, SWT.NULL);
		label4.setText("Parameter4");
		label4 = new Label(container, SWT.NULL);
		label4.setText("Parameter5");

		//testCaseGenTable.createTable(container,testGenData);
		for (int i = 0; i < numberOfRows; i++) {
			for (int j = 0; j < numberOfCols; j++) {
				if (j == 0) {
					combo[i] = new CCombo(container, SWT.NONE);
					combo[i].setItems(items);
					combo[i].setLayoutData(gd);
				} else {
					txtBox[i][j] = new Text(container, SWT.NONE);
					txtBox[i][j].setLayoutData(gd);
					txtBox[i][j].addModifyListener(new ModifyListener() {
						@Override
						public void modifyText(ModifyEvent e) {
							Text text = (Text) e.widget;
							// System.out.println(text.getText());
						}
					});
				}
			}
			System.out.println("\n");
		}
		setControl(container);
	}

	public IWizardPage getNextPage() {
		super.getNextPage();
		IWizard wiz = getWizard();
		System.out.println("i m in getnextpage");

		iter = cmmethods.iterator();
		while (iter.hasNext()) {
			CMemberMethod cmm = iter.next();
			if (methodNames.getText().equals(cmm.getMethodName())) {
				System.out.println("method " + cmm.getParams());
				// assertValues.add(cmm.getParams());
				hashMethods.put(methodNames.getText(), cmm.getParams());
			}
		}

		System.out.println(methodNames.getText());

		return wiz.getNextPage(this);

	}

	public ArrayList<CMemberMethod> MethodsInCUT() {

		Iterator<CMemberMethod> itr2;
		Iterator<ArrayList<CMemberMethod>> itr;
		ArrayList<CMemberMethod> cmlist;

		String title = part.getTitle();
		String[] className = title.split(".java");

		className[0].substring(4);
		methods = init((IStructuredSelection) selection).getMethodHash();
		getInitialJavaElement((IStructuredSelection) selection);
		// createCClass (IJavaElement element ,String fileName);
		alist = new ArrayList<ArrayList<CMemberMethod>>(methods.values());
		memberMethod = new ArrayList<CMemberMethod>();
		itr = alist.iterator();

		while (itr.hasNext()) {

			cmlist = itr.next();
			itr2 = cmlist.iterator();
			while (itr2.hasNext()) {

				CMemberMethod cmm = itr2.next();
				if (cmm.getParams() != null) {
					for (int i = 0; i < cmm.getParams().size(); i++) {
						methodsParameters.add(cmm.getParams().get(i));
						System.out.println("parameter Type"
								+ cmm.getParameterType(i));
						makeTextNonEditable(cmm, cmm.getFullSignature());
					}
				}
				memberMethod.add(cmm);
			}
		}
		return memberMethod;
	}

	public CClass init(IStructuredSelection selection)  {
		HashMap<String,CClass> classobj;
		IJavaElement element = getInitialJavaElement(selection);
		CClassBuilder clsBuilder=new CClassBuilder(element);
		classobj=clsBuilder.getCClassCollection();
		testGenData.setTestClass(classobj.get(element.getElementName().substring(0, element.getElementName().length()-CerberusConstants.TEST_CLASS_EXTENSION.length())));
		testGenData.setCut(classobj.get(element.getElementName().substring(CerberusConstants.TEST_ANNOTATION_NAME.length(), element.getElementName().length()-CerberusConstants.TEST_CLASS_EXTENSION.length())));
		testGenData.setType(clsBuilder.getType());
		System.out.println("Hello Test Class: "+testGenData.getTestClass());
		return testGenData.getCut();
	}

	public TestGenerationData populateTestGenData(){
		readData();
		return testGenData;

	}

	public void readData() {
		ArrayList<MethodTestData> methodTestData=new ArrayList<MethodTestData>();
		MethodTestData methTestData= new MethodTestData();
		methTestData.setSignature(methodNames.getText());
		methodTestData.add(methTestData);
		JUnitMethodCheck jcheck = new JUnitMethodCheck();
		ArrayList<String> param = new ArrayList<String>();
		for (int i = 0; i < numberOfRows; i++) {
			for (int j = 0; j < numberOfCols; j++) {
				//				if (j == 0) {
				//					data[i][j] = lbl[i].getText();
				//				} else 
				if (j == 0) {
					if (combo[i].getSelectionIndex() != -1)
						data[i][j] = items[combo[i].getSelectionIndex()];
					jcheck.setValue(data[i][j]);
				} else if (j == 1) {
					data[i][j] = txtBox[i][j].getText();
					methTestData.setExpected(data[i][j]);
				} else if (j == 2) {
					data[i][j] = txtBox[i][j].getText();
					param.add(data[i][j]);
				} else if (j == 3) {
					data[i][j] = txtBox[i][j].getText();
					param.add(data[i][j]);
				} else if (j == 4) {
					data[i][j] = txtBox[i][j].getText();
					param.add(data[i][j]);
				} else if (j == 5) {
					data[i][j] = txtBox[i][j].getText();
					param.add(data[i][j]);
				} else if (j == 6) {
					data[i][j] = txtBox[i][j].getText();
					param.add(data[i][j]);
				}
				System.out.print(data[i][j] + "\t");
			}
			System.out.println("");

		}
		methTestData.setAssertCheck(jcheck);
		methTestData.setSignature(methodNames.getText());
		String name = methodNames.getText(); 
		if(name.trim().isEmpty()){
			//TODO
			CerberusMethodsDelegate.createPopupDialogue(
					CerberusConstants.WINDOW_TITLE,
					CerberusConstants.COMBO_BLANK);
		}
		else {
			StringTokenizer st  = new StringTokenizer(name," ");
			String val=null;		
			st.nextToken();
			val = st.nextToken();			 
			methTestData.setName(val);
			methTestData.setParam(param);
			testGenData.setMethodTestData(methodTestData);
		}
	}

	public int getselectionVal() {
		System.out.println("methods Names selected:   "
				+ methodNames.getItems() + "  " + methodNames.getText()
				+ "getselected item" + methodNames.getText());
		return methodNames.getSelectionIndex();
	}

	public HashMap<String, ArrayList<String>> getHash() {
		return hashMethods;
	}

	public String getFileName() {
		return fileText.getText();
	}
	 
	private int makeTextNonEditable(CMemberMethod row,String methodSignature){
			int noOfColumns = 0;
			if(methodSignature.equalsIgnoreCase(row.getFullSignature()) && (row.getParams()!= null)){
				noOfColumns = row.getParams().size();
			}
			//Text boxes excluding First and second column
			return noOfColumns+2;
		}
	
}